<template>
  <div class="drawContainer">
    <div id="map" class="mapContent" />

    <div class="videoCont">
      <div
        class="arrow"
        :class="{ 'arrow-left': showVideo }"
        @click="showVideo = !showVideo"
        v-text="'<<'"
      />
      <VideoPlayer v-show="showVideo" ref="videoRef" class="video-player" :options="getVideoOptions" @time-update="timeUpdate" />
    </div>
  </div>
</template>

<script>
// openlayers 类
import 'ol/ol.css'
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import XYZ from 'ol/source/XYZ'
import { Map, View, Feature } from 'ol'
import { Point } from 'ol/geom'
import * as control from 'ol/control'
import * as interaction from 'ol/interaction'
import { fromLonLat } from 'ol/proj'
import { LineString } from 'ol/geom'
// 其他组件
import gcj02Mecator from '@/utils/map/gcj02Mecator.js'
import VideoPlayer from '@/components/VideoPlayer/index.vue'
import { ref, reactive, toRefs, onMounted, onBeforeUnmount, computed } from 'vue'
import { getFlightData } from '@/api/flight-data/index.js'
import { geomStyles } from '@/utils/map/geomStyle'
import { getTaskVideo } from '@/api/task/index.js'
export default {
  name: 'DrawComp',
  components: { VideoPlayer },
  props: {
    detail: {
      type: Object,
      required: true
    },
    drawTitle: {
      type: String,
      required: true
    },
    liveVideoShow: {
      type: Boolean,
      required: true
    }
  },
  setup(props) {
    const videoRef = ref()
    const data = reactive({
      map: null,
      view: null,
      tdtLineMap: null,
      showVideo: true,
      videoUrl: null,
      liveTimer: null, // 直播定时器
      live: false
    })

    const getVideoOptions = computed(() => {
      return {
        videoUrl: data.videoUrl || null,
        videoTitle: null,
        live: data.live
      }
    })
    if (props.detail) {
      if (props.detail?.id) {
        getTaskVideo(props.detail?.id).then(res => {
          if (res.code === 0) {
            data.videoUrl = res.data?.aipullUrl ? res.data?.aipullUrl : res.data?.aiVideoUrl
            if (res.data?.aipullUrl) {
              // 直播
              data.live = true
              data.liveTimer = setInterval(() => {
                getFlightData(props.detail?.id).then(res => {
                  if (res.code === 0) {
                    const coords = formatLngLat(res.data)
                    if (data.trackInfo) {
                      const len = coords.length
                      // 实时更新无人机路径和无人机位置
                      data.trackInfo.route.appendCoordinate(coords[len - 1])
                      data.trackInfo.geoMarker.getGeometry().setCoordinates(data.trackInfo.route.getLastCoordinate())
                      data.trackInfo.vectorLayer.getSource().changed()
                    } else {
                      data.trackInfo = initTrack(coords)
                    }
                  }
                })
              }, 1000)
            }
            if (res.data?.aiVideoUrl) {
              getFlightData(props.detail?.id).then(res => {
                if (res.code === 0) {
                  const coords = formatLngLat(res.data)
                  data.trackInfo = initTrack(coords)
                }
              })
            }
          }
        })
      }
    }

    /**
     *  初始化地图
     */
    const initMap = () => {
      // 电子地图
      data.tdtLineMap = new TileLayer({
        visible: true,
        source: new XYZ({
          projection: gcj02Mecator,
          url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
          // url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=f634525a82da65f715d168d7ba1899c0'
        })
      })

      data.view = new View({
        zoom: 9.5,
        maxZoom: 18,
        center: fromLonLat([119.7286, 32.0445])
      })

      data.map = new Map({
        target: 'map',
        view: data.view,
        layers: [data.tdtLineMap],
        controls: control.defaults({
          attribution: false,
          rotate: false,
          zoom: false
        }),
        interactions: interaction.defaults({
          // 禁止地图双击放大事件
          doubleClickZoom: false
        })
      })

      // 鼠标移到要素上时改变鼠标样式,由箭头变成小手
      data.map.on('pointermove', function(evt) {
        data.map.getTargetElement().style.cursor = data.map.hasFeatureAtPixel(evt.pixel)
          ? 'pointer'
          : ''
      })
    }

    /**
     * 格式化数据
     * @param {*} coord
     */
    const formatLngLat = (coord) => {
      const lngLat = []
      if (coord?.length) {
        coord.map(item => {
          lngLat.push(fromLonLat([parseFloat(item?.lng || item?.lon), parseFloat(item.lat)]))
        })
      }
      return lngLat
    }

    /**
     * 初始轨迹
     * @param {*} coordinate
     */
    const initTrack = (coordinate) => {
      let vectorLayer = null
      const route = new LineString(coordinate)
      // 新建轨迹数据源
      const routeFeature = new Feature({
        type: 'route',
        geometry: route
      })
      // 新建点数据源
      const geoMarker = new Feature({
        type: 'geoMarker',
        geometry: new Point(route.getLastCoordinate())
      })
      // 统计创建矢量图层
      vectorLayer = new VectorLayer({
        source: new VectorSource({
          features: [geoMarker, routeFeature]
        }),
        style: function(feature) {
          return geomStyles(feature.get('type'))
        },
        zIndex: getMaxZLayer() + 1
      })

      data.trackLayer = vectorLayer
      data.map.addLayer(data.trackLayer)
      data.view.fit(route, { padding: [50, 50, 50, 50] })
      return {
        vectorLayer,
        geoMarker,
        route
      }
    }

    const timeUpdate = (time) => {
      if (props.detail?.live === false) {
        const percent = time / videoRef.value.getDuration()
        // 实时更新无人机路径和无人机位置
        data.trackInfo.geoMarker.getGeometry().setCoordinates(data.trackInfo.route.getCoordinateAt(percent))
        data.trackInfo.vectorLayer.getSource().changed()
      }
    }

    /**
     *  获取所有图层中最大的z-index
     */
    const getMaxZLayer = () => {
      let maxZIndex = 0
      const layers = data.map.getAllLayers()
      if (layers.length) {
        layers.map((lay) => {
          const zIndex = lay.getZIndex()
          if (zIndex > maxZIndex) {
            maxZIndex = zIndex
          }
        })
      }
      return maxZIndex
    }

    onMounted(() => {
      initMap()
    })

    onBeforeUnmount(() => {
      // 清除定时器
      if (data.liveTimer !== null) {
        clearInterval(data.liveTimer)
        data.liveTimer = null
      }
    })

    return {
      ...toRefs(data),
      getVideoOptions,
      timeUpdate,
      videoRef
    }
  }

}
</script>

<style lang="scss" scoped>
.drawContainer {
  position: relative;
  width: 100%;
  height: 100%;
  .mapContent {
    width: 100%;
    height: 100%;
  }
  .videoCont {
    position: absolute;
    top: 20px;
    right: 20px;
    background-color: #fff;
    .arrow {
      position: absolute;
      right: 10px;
      width: 30px;
      height: 25px;
      line-height: 25px;
      text-align: center;
      background-color: #fff;
      cursor: pointer;
    }
    .arrow-left {
      transform-origin: center;
      transform: rotateZ(180deg);
    }

    .video-player {
      margin-top: 25px;
      width: 583px;
      height: 300px;
    }
  }
}
</style>
